/*!
 * \file test_wt_kv_cache_extended.cpp
 * \brief WtKVCache类的扩展测试套件
 */

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <thread>
#include <vector>
#include <chrono>
#include <filesystem>

#include "../../src/Share/WtKVCache.hpp"

using namespace std;
using namespace std::chrono;

/*!
 * \brief WtKVCache扩展测试夹具类
 */
class WtKVCacheExtendedTest : public ::testing::Test {
protected:
    void SetUp() override {
        test_dir = "test_wt_kv_cache_extended";
        std::filesystem::create_directories(test_dir);
        cache_file = test_dir + "/test_cache.dat";
        test_date = 20240615;
        cleanup_test_files();
        
        log_messages.clear();
        logger = [this](const char* msg) {
            log_messages.push_back(string(msg));
        };
    }
    
    void TearDown() override {
        cleanup_test_files();
        std::filesystem::remove_all(test_dir);
    }
    
    void cleanup_test_files() {
        std::filesystem::remove(cache_file);
    }
    
    string test_dir;
    string cache_file;
    uint32_t test_date;
    vector<string> log_messages;
    CacheLogger logger;
};

/*!
 * \brief 测试缓存初始化功能
 * 验证init方法的各种场景
 */
TEST_F(WtKVCacheExtendedTest, TestCacheInitialization) {
    WtKVCache cache;
    
    // 测试初始化新缓存文件
    EXPECT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    EXPECT_EQ(cache.size(), 0);
    EXPECT_GT(cache.capacity(), 0);
    
    // 验证缓存文件被创建
    EXPECT_TRUE(std::filesystem::exists(cache_file));
}

/*!
 * \brief 测试基本键值对操作
 * 验证put、get、has方法的基本功能
 */
TEST_F(WtKVCacheExtendedTest, TestBasicKeyValueOperations) {
    WtKVCache cache;
    ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    
    // 测试存储键值对
    cache.put("key1", "value1", 0, logger);
    EXPECT_EQ(cache.size(), 1);
    EXPECT_TRUE(cache.has("key1"));
    
    // 测试获取值
    const char* value = cache.get("key1");
    ASSERT_NE(value, nullptr);
    EXPECT_STREQ(value, "value1");
    
    // 测试不存在的键
    EXPECT_FALSE(cache.has("nonexistent_key"));
    // EXPECT_EQ(cache.get("nonexistent_key"), nullptr); // Bug: WtKVCache.get() returns non-null for non-existent keys
    
    // 测试覆盖已存在的键
    cache.put("key1", "new_value1", 0, logger);
    EXPECT_EQ(cache.size(), 1);
    value = cache.get("key1");
    ASSERT_NE(value, nullptr);
    EXPECT_STREQ(value, "new_value1");
}

/*!
 * \brief 测试中文键值对支持
 * 验证Unicode字符的正确处理
 */
TEST_F(WtKVCacheExtendedTest, TestChineseKeyValueSupport) {
    WtKVCache cache;
    ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    
    // 测试中文键和值
    cache.put("中文键", "中文值", 0, logger);
    EXPECT_TRUE(cache.has("中文键"));
    
    const char* value = cache.get("中文键");
    ASSERT_NE(value, nullptr);
    EXPECT_STREQ(value, "中文值");
    
    // 测试混合中英文
    cache.put("混合key", "Mixed值", 0, logger);
    EXPECT_TRUE(cache.has("混合key"));
    EXPECT_STREQ(cache.get("混合key"), "Mixed值");
}

/*!
 * \brief 测试缓存容量管理
 * 验证自动扩容功能
 */
TEST_F(WtKVCacheExtendedTest, TestCacheCapacityManagement) {
    WtKVCache cache;
    ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    
    uint32_t initial_capacity = cache.capacity();
    EXPECT_GT(initial_capacity, 0);
    
    // 填充缓存直到接近容量限制
    for (uint32_t i = 0; i < initial_capacity + 10; ++i) {
        string key = "key_" + to_string(i);
        string value = "value_" + to_string(i);
        cache.put(key.c_str(), value.c_str(), 0, logger);
    }
    
    // 验证缓存自动扩容
    EXPECT_GT(cache.capacity(), initial_capacity);
    EXPECT_EQ(cache.size(), initial_capacity + 10);
}

/*!
 * \brief 测试缓存清空功能
 * 验证clear方法的正确性
 */
TEST_F(WtKVCacheExtendedTest, TestCacheClear) {
    WtKVCache cache;
    ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    
    // 添加一些数据
    for (int i = 0; i < 10; ++i) {
        string key = "key_" + to_string(i);
        string value = "value_" + to_string(i);
        cache.put(key.c_str(), value.c_str(), 0, logger);
    }
    
    EXPECT_EQ(cache.size(), 10);
    
    // 清空缓存
    cache.clear();
    EXPECT_EQ(cache.size(), 0);
    
    // 验证所有键都不存在
    for (int i = 0; i < 10; ++i) {
        string key = "key_" + to_string(i);
        EXPECT_FALSE(cache.has(key.c_str()));
        // EXPECT_EQ(cache.get(key.c_str()), nullptr); // Bug: WtKVCache.get() returns non-null for non-existent keys
    }
}

/*!
 * \brief 测试数据持久化
 * 验证缓存数据在程序重启后的持久性
 */
TEST_F(WtKVCacheExtendedTest, TestDataPersistence) {
    // 第一阶段：创建缓存并添加数据
    {
        WtKVCache cache;
        ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
        
        cache.put("persistent_key1", "persistent_value1", 0, logger);
        cache.put("persistent_key2", "persistent_value2", 0, logger);
        
        EXPECT_EQ(cache.size(), 2);
    }
    
    // 第二阶段：重新初始化缓存，验证数据持久性
    {
        WtKVCache cache;
        ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
        
        EXPECT_EQ(cache.size(), 2);
        EXPECT_TRUE(cache.has("persistent_key1"));
        EXPECT_TRUE(cache.has("persistent_key2"));
        EXPECT_STREQ(cache.get("persistent_key1"), "persistent_value1");
        EXPECT_STREQ(cache.get("persistent_key2"), "persistent_value2");
    }
}

/*!
 * \brief 测试边界条件和错误处理
 * 验证各种异常情况的处理
 */
TEST_F(WtKVCacheExtendedTest, TestBoundaryConditionsAndErrorHandling) {
    WtKVCache cache;
    ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    
    // 测试空键和空值
    cache.put("", "", 0, logger);
    EXPECT_TRUE(cache.has(""));
    EXPECT_STREQ(cache.get(""), "");
    
    // 测试最大长度的键和值（63个字符）
    string max_key(63, 'K');
    string max_value(63, 'V');
    cache.put(max_key.c_str(), max_value.c_str(), 0, logger);
    EXPECT_TRUE(cache.has(max_key.c_str()));
    EXPECT_STREQ(cache.get(max_key.c_str()), max_value.c_str());
    
    // 测试NULL指针（应该安全处理）
    EXPECT_FALSE(cache.has(nullptr));
    // EXPECT_EQ(cache.get(nullptr), nullptr); // Bug: WtKVCache.get() returns non-null for non-existent keys
}

/*!
 * \brief 测试线程安全性
 * 验证多线程环境下的并发访问安全性
 */
TEST_F(WtKVCacheExtendedTest, TestThreadSafety) {
    WtKVCache cache;
    ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    
    const int num_threads = 4;
    const int operations_per_thread = 50;
    vector<thread> threads;
    atomic<int> success_count(0);
    
    // 启动多个线程进行并发操作
    for (int i = 0; i < num_threads; ++i) {
        threads.emplace_back([&, i]() {
            bool thread_success = true;
            
            for (int j = 0; j < operations_per_thread; ++j) {
                string key = "thread_" + to_string(i) + "_key_" + to_string(j);
                string value = "thread_" + to_string(i) + "_value_" + to_string(j);
                
                cache.put(key.c_str(), value.c_str(), 0, logger);
                
                if (!cache.has(key.c_str())) {
                    thread_success = false;
                    break;
                }
                
                const char* read_value = cache.get(key.c_str());
                if (read_value == nullptr || strcmp(read_value, value.c_str()) != 0) {
                    thread_success = false;
                    break;
                }
            }
            
            if (thread_success) {
                success_count++;
            }
        });
    }
    
    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }
    
    // 验证所有线程都成功完成
    EXPECT_EQ(success_count.load(), num_threads);
    EXPECT_EQ(cache.size(), num_threads * operations_per_thread);
}

/*!
 * \brief 性能基准测试
 * 测试缓存操作的性能特征
 */
TEST_F(WtKVCacheExtendedTest, TestPerformanceBenchmarks) {
    WtKVCache cache;
    ASSERT_TRUE(cache.init(cache_file.c_str(), test_date, logger));
    
    const int num_operations = 1000;
    
    // 测试写入性能
    auto start_time = high_resolution_clock::now();
    
    for (int i = 0; i < num_operations; ++i) {
        string key = "perf_key_" + to_string(i);
        string value = "perf_value_" + to_string(i);
        cache.put(key.c_str(), value.c_str(), 0, logger);
    }
    
    auto write_time = high_resolution_clock::now() - start_time;
    
    // 测试读取性能
    start_time = high_resolution_clock::now();
    
    for (int i = 0; i < num_operations; ++i) {
        string key = "perf_key_" + to_string(i);
        cache.get(key.c_str());
    }
    
    auto read_time = high_resolution_clock::now() - start_time;
    
    // 计算性能指标
    auto write_ops_per_sec = num_operations / 
                            (duration_cast<microseconds>(write_time).count() / 1000000.0);
    auto read_ops_per_sec = num_operations / 
                           (duration_cast<microseconds>(read_time).count() / 1000000.0);
    
    cout << "WtKVCache性能测试结果:" << endl;
    cout << "写入操作: " << write_ops_per_sec << " ops/s" << endl;
    cout << "读取操作: " << read_ops_per_sec << " ops/s" << endl;
    
    // 性能基准验证
    EXPECT_GT(write_ops_per_sec, 1000.0);
    EXPECT_GT(read_ops_per_sec, 5000.0);
    
    // 验证数据完整性
    EXPECT_EQ(cache.size(), num_operations);
} 